package client

import (
	"awesomeTask/application/timer"
	"awesomeTask/application/variable"
	awesomeTask2 "awesomeTask/commom"
	"awesomeTask/commom/KeyHelper"
	"awesomeTask/commom/MessageHelper"
	"awesomeTask/commom/locationHelper"
	awesomeTask "awesomeTask/config"
	"awesomeTask/system/echo"
	event2 "awesomeTask/system/event"
	"awesomeTask/system/helper"
	"awesomeTask/system/kernel"
	"awesomeTask/system/log"
	"awesomeTask/system/tcpClient"
	"awesomeTask/system/udpServer"
	"fmt"
	"net"
	_ "os"
	"strconv"
	"strings"
	"time"
	_ "time"
)

var ServerCon net.Conn

func GetServerCon() net.Conn {
	for true {
		if ServerCon != nil {
			return ServerCon
		}
		time.Sleep(time.Second)
	}
	return nil
}
func GetServerLocation() map[string]string {
	con := GetServerCon()
	ip := strings.Split(con.RemoteAddr().String(), ":")[0]
	for _, conn := range Nodes {
		if conn.IsMaster {
			return conn.Location.(map[string]string)
		}
	}
	for _, conn := range Nodes {
		if conn.Connetion.RemoteAddr() == con.RemoteAddr() && conn.IsInit {
			return conn.Location.(map[string]string)
		}
	}
	if ip == "127.0.0.1" {
		return awesomeTask.GetConfigByKey("location").(map[string]string)
	} else {
		fmt.Println(ip, "ip==============>")
		res, _ := locationHelper.GetLocationByIp(ip)
		return res
	}
}
func SendToServer(conn net.Conn, message string) interface{} {
	_, err := conn.Write([]byte(message))
	if err != nil {
		return true
	}
	return err
}
func askToConnectServer(conn net.Conn) {
	data := make(map[string]interface{})
	data["listenIpAddress"] = awesomeTask.GetConfigByKey("listenIpAddress")
	data["listenPort"] = awesomeTask.GetConfigByKey("listenPort")
	MessageHelper.SendEvent(variable.ON_ASK_CONNECT_SERVER, data, conn)
}

/**
在k8s 进行服务发现,原理 kubernets 提供了 headless service 此service 对此service进行dns 查询可以获取与其绑定的pod ip地址
*/
func runNodeFindProcess(host string) {
	ips, err := udpServer.DnsQuery(host)
	if err != nil {
		return
	}
	targetPort := awesomeTask.GetConfigByKey("listenPort").(float64)
	for _, ip := range ips {
		podIpAddress := ip.String()
		uniqueID := KeyHelper.TcpUniqueId(podIpAddress, int(targetPort))
		if _, ok := variable.ServerConnections.Load(uniqueID); ok {
			//连接存在 不用处理
			continue
		}
		CreateNewClient(podIpAddress, int(targetPort))
	}
}
func RunAsNode() {
	config := awesomeTask.InitConfig()
	managerConfig := config["node"].(map[string]interface{})["manager"].(map[string]interface{})
	port, _ := strconv.Atoi(managerConfig["port"].(string))
	event2.Dispatch("runAsNode")
	CreateNewClient("127.0.0.1", int(awesomeTask.GetConfigByKey("listenPort").(float64)))
	host, err := echo.GetCmdInputParamByKey(variable.K8S_HEAD_LESS_SERVICE)
	if err == nil {
		log.GetLogger().Warn("使用k8s service head less 进行服务发现")
		timer.SetTimeInterval(func() {
			runNodeFindProcess(host)
		}, 30) //30秒进行一次服务发现
	} else {
		CreateNewClient(managerConfig["ipAddress"].(string), port)
	}
}
func CreateNewClient(IpAddress string, port int) tcpClient.TcpClient {
	clinet := tcpClient.TcpClient{}
	clinet.OnConnect(func(connection net.Conn) {
		//ServerCon = connection
		uniqueID := KeyHelper.TcpUniqueId(IpAddress, port)
		variable.ServerConnections.Store(uniqueID, connection)
		askToConnectServer(connection)
		EventClientHandlerObj{}.PostNodeStatusOne(connection)
	})
	clinet.OnMessage(func(connection net.Conn, data string) {
		echo.Red("客户端接受到数据:" + connection.RemoteAddr().String() + data)
		if awesomeTask2.SafeCheck(data) == false {
			connection.Close()
			log.GetLogger().Error("主动断开服务器连接:无效的clientToken,msg:" + data)
			return
		}
		eventInfo := helper.JsonDecode(data).(map[string]interface{})
		eventInfo["connection"] = connection
		instance := kernel.GetIocInstance()
		if _, ok := variable.EventServerMap[eventInfo["event"].(string)]; ok {
			echo.Green("客户端已经注册事件回调不在使用Handler:" + eventInfo["event"].(string))
			event2.Dispatch(eventInfo["event"].(string), eventInfo)
			return
		}
		if event2.HasTmpEvent(eventInfo["event"].(string)) {
			event2.Dispatch(eventInfo["event"].(string), eventInfo)
			return
		}
		obj := instance.GetInstanceOrCreate(variable.ClientEventHandlerInstance).(*EventClientHandlerObj)
		go instance.CallFunByName(obj, eventInfo["event"].(string), eventInfo)
	})
	clinet.OnClose(func(conn net.Conn) {
		log.GetLogger().Error("与服务器的连接断开:" + conn.RemoteAddr().String())
		uniqueID := KeyHelper.TcpUniqueId(IpAddress, port)
		variable.ServerConnections.Delete(uniqueID)
		RemoveConnection(conn)
		if ServerCon != nil {
			if ServerCon.RemoteAddr().String() == conn.RemoteAddr().String() {
				ServerCon = nil
				variable.VoteIsFinish = false
				log.GetLogger().Error("与主节点的连接断开:" + conn.RemoteAddr().String())
				event2.Dispatch(variable.ON_MASTER_DISCONNECTED)
			}
		}
		event2.Dispatch(variable.ON_LOSE_CONNECTION, IpAddress, port)
		//drt
	})
	go clinet.Connect(IpAddress, port, false)
	return clinet
}
